﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

using zijian666.DI.Features;

namespace zijian666.DI;

/// <summary>
/// 宿主服务, 触发过滤器, 执行 Startup.Configure 和 Startup.Stop
/// </summary>
internal sealed class HostedService(IServiceProvider provider) : IHostedService
{
    private readonly IServiceProvider _provider = provider ?? throw new ArgumentNullException(nameof(provider));

    private readonly ILogger<HostedService>? _logger= provider.GetService<ILogger<HostedService>>();

    async Task IHostedService.StartAsync(CancellationToken cancellationToken)
    {
        var useStartupFilter = _provider.GetServices<IHostedService>().Any(x => x.GetType()?.Namespace?.StartsWith("Microsoft.AspNet") ?? false);
        // StartupFilter 接管
        if (useStartupFilter && _provider.GetService<StartupFilter>() is not null)
        {
            return;
        }
        if (StartupFilter.Exception is not null)
        {
            _logger?.LogError(StartupFilter.Exception, "StartupFilter异常");
        }
        await _provider.ConfigureAsync(cancellationToken);
    }

    async Task IHostedService.StopAsync(CancellationToken cancellationToken)
    {
        var launchers = _provider.GetServices<ILauncher>() ?? [];
        foreach (var launcher in launchers)
        {
            try
            {
                await launcher.StopAsync(_provider, [], cancellationToken);
            }
            catch (Exception e)
            {
                _logger?.LogError(e, "StopAsync异常");
            }
        }
    }

    public static void Register(IServiceCollection services)
    {
        if (services.Any(x => x.ServiceType == typeof(IHostedService) && x.ImplementationType == typeof(HostedService)))
        {
            return;
        }
        services.AddSingleton<IHostedService, HostedService>();
    }
}
